package io.rong.imkit.webview

import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.text.TextUtils
import android.util.AttributeSet
import android.util.Log
import android.webkit.WebSettings
import android.webkit.WebView
import com.custom.base.util.SDBase64
import java.io.File

open class CustomWebView(context: Context, attrs: AttributeSet?) : WebView(context, attrs) {
    private var webViewClient: DefaultWebViewClient? = null
    private var webChromeClient: DefaultWebChromeClient? = null
    var cacheDir: File? = null
        private set
    var isImgSrcClick = false

    init {
        init()
    }

    fun setListenerWebViewClient(listener: WebViewClientListener?) {
        webViewClient?.setListener(listener, this@CustomWebView, isImgSrcClick)
    }

    fun setListenerWebChromeClient(listener: WebChromeClientListener?) {
        webChromeClient?.setListener(listener)
    }

    protected fun init() {
        val cacheDirPath =
            context.cacheDir.absolutePath + WEBVIEW_CACHE_DIR
        cacheDir = File(cacheDirPath)
        cacheDir?.apply {
            if (!exists()) {
                mkdirs()
            }
        }
        webViewClient = DefaultWebViewClient()
        webChromeClient = DefaultWebChromeClient()
        initSettings(settings)
        setWebViewClient(webViewClient!!)
        setWebChromeClient(webChromeClient)
        setDownloadListener { url, _, _, _, _ ->
            val uri = Uri.parse(url)
            val intent = Intent(Intent.ACTION_VIEW, uri)
            this@CustomWebView.context.startActivity(intent)
        }
        requestFocus()
    }

    @SuppressLint("SetJavaScriptEnabled", "SdCardPath","joinVIP")
    protected fun initSettings(settings: WebSettings) {
        setScaleToShowAll(true)
        setSupportZoom(true)
        setDisplayZoomControls(false)
        settings.defaultTextEncodingName = "utf-8"
        settings.javaScriptEnabled = true
        settings.allowFileAccess = true
        settings.javaScriptEnabled = true
        settings.domStorageEnabled = true // 开启DOM storage API 功能
        settings.cacheMode = WebSettings.LOAD_DEFAULT
        settings.layoutAlgorithm = WebSettings.LayoutAlgorithm.NARROW_COLUMNS
        settings.savePassword = false
        settings.blockNetworkImage = false
        settings.mixedContentMode = WebSettings.MIXED_CONTENT_ALWAYS_ALLOW
        settings.setGeolocationEnabled(true)
        cacheDir?.apply {
            settings.setGeolocationDatabasePath(absolutePath)
            settings.databasePath = absolutePath
//            settings.setAppCachePath(absolutePath)
        }

        // Database
        settings.databaseEnabled = true

        // AppCache
//        settings.setAppCacheEnabled(true)
//        settings.setAppCacheMaxSize(1024 * 1024 * 8.toLong())
//        var us = settings.userAgentString
//        us += " sdk_version_name/${SDPackageUtil.versionName} sdk_version/" + SDPackageUtil.versionCode + " sdk_guid/"+SDPackageUtil.deviceId + " screen_width/" + SDViewUtil.screenWidth + " screen_height/" + SDViewUtil.screenHeight+" type/android";
//        settings.userAgentString = us

        // 详情回调处理
        val detailHandler: AppJsHandler = object : AppJsHandler() {}
        addJavascriptInterface(detailHandler)
    }

    fun setScaleToShowAll(isScaleToShowAll: Boolean) {
        settings.loadWithOverviewMode = isScaleToShowAll
        settings.useWideViewPort = isScaleToShowAll
    }

    fun setSupportZoom(isSupportZoom: Boolean) {
        settings.setSupportZoom(isSupportZoom)
        settings.builtInZoomControls = isSupportZoom
    }

    fun setDisplayZoomControls(display: Boolean) {
        settings.displayZoomControls = display
    }

    @SuppressLint("JavascriptInterface")
    fun addJavascriptInterface(handler: BaseJsHandler?) {
        if (handler != null) {
            addJavascriptInterface(handler, handler.name)
        }
    }

    operator fun get(url: String?, mapHeader: Map<String?, String?>?) {
        get(url, null, mapHeader)
    }

    // get
    @JvmOverloads
    operator fun get(
        url: String?,
        params: RequestParams? = null,
        mapHeader: Map<String?, String?>? = null
    ) {
        var url = url
        if (TextUtils.isEmpty(url)) {
            return
        }
        if (params != null) {
            url = params.build(url!!)
        }
        url?.apply {
            if (mapHeader != null && mapHeader.isNotEmpty()) {
                loadUrl(url, mapHeader)
            } else {
                loadUrl(url)
            }
            Log.d("webview", url)
        }
    }

    // post
    @JvmOverloads
    fun post(url: String, params: RequestParams? = null) {
        if (TextUtils.isEmpty(url)) {
            return
        }
        var postData: ByteArray? = null
        if (params != null) {
            val data = params.build()
            data?.apply {
                if (!TextUtils.isEmpty(this)) {
                    postData = SDBase64.encodeToByte(this)
                }
            }
        }
        postUrl(url, postData!!)
    }

    fun loadJsFunction(function: String, vararg params: Any) {
        loadJsFunction(buildJsFunctionString(function, *params))
    }

    fun buildJsFunctionString(function: String, vararg params: Any): String {
        val sb = StringBuilder()
        if (!TextUtils.isEmpty(function)) {
            sb.append(function).append("(")
            if (params != null && params.isNotEmpty()) {
                for (param in params) {
                    if (param is String) {
                        sb.append("'").append(param.toString()).append("'")
                    } else {
                        sb.append(param.toString())
                    }
                    sb.append(",")
                }
                sb.setLength(sb.length - 1)
            }
            sb.append(")")
        }
        return sb.toString()
    }

    @SuppressLint("NewApi")
    fun loadJsFunction(js: String) {
        if (!TextUtils.isEmpty(js)) {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                evaluateJavascript(js) { }
            } else {
                loadUrl("javascript:$js")
            }
        }
    }

    companion object {
        private const val WEBVIEW_CACHE_DIR = "/webviewcache" // web缓存目录
    }
}